from Ui_main import Ui_Form
from Ui_confirmation import Ui_Dialog
from PyQt5 import QtWidgets, QtGui, QtCore
from PyQt5.QtWidgets import QDialog, QMessageBox
import pca
import my_camera
import sys
import cv2
import cupy as cp
import logging

logging.basicConfig(level=logging.DEBUG, format='%(asctime)s - %(levelname)s - %(message)s')
#调用Ui_main.py中的Ui_Form类
class MyForm(QtWidgets.QWidget, Ui_Form):   
    def __init__(self, parent=None):
        super(MyForm, self).__init__(parent) # 调用父类构造函数
        self.setupUi(self) # 调用setupUi函数
        self.camera_id = my_camera.find_available_cameras() #获取可用摄像头
        self.id = 0 #摄像头id
        self.face = None #人脸图像

        self.label_4.setText("")
        self.label_6.setText("")
        self.label_8.setText("")
        self.label_10.setText("")
        self.label_12.setText("")
        self.label_14.setText("")


        self.pushButton.clicked.connect(self.open_camera) #打开摄像头按钮槽函数
        self.pushButton_3.clicked.connect(self.close_camera) #关闭摄像头按钮槽函数
        self.pushButton_2.clicked.connect(self.switch_camera) #切换摄像头按钮槽函数
        self.pushButton_4.clicked.connect(self.confirmation_dialog) #确认按钮槽函数

    #构建信号槽
    #打开摄像头槽函数
    def open_camera(self):
        self.cap = cv2.VideoCapture(self.camera_id[self.id]) #打开摄像头
        self.timer = QtCore.QTimer(self) #创建定时器
        self.timer.timeout.connect(self.show_camera) #定时器超时连接show_camera函数
        self.timer.start(30) #定时器开始，每隔30ms调用一次show_camera函数
        logging.info(f"camera opened, id: {self.camera_id[self.id]}")

    #关闭摄像头槽函数
    def close_camera(self):
        self.cap.release() #释放摄像头
        self.timer.stop() #停止定时器
        logging.info("camera closed")

    #切换摄像头槽函数
    def switch_camera(self):
        if len(self.camera_id) > 1:  # 确保至少有多个摄像头可以切换
            self.cap.release()  # 释放当前摄像头
            self.id = (self.id + 1) % len(self.camera_id)  # 让 self.id 循环更新
            self.cap = cv2.VideoCapture(self.camera_id[self.id])  # 打开新的摄像头
            self.timer.start(30)  # 继续刷新
            logging.info(f"camera changed, id: {self.camera_id[self.id]}")  # 调试信息


    def display_recognition_results(self, results):
        # 假设返回的结果是人名和置信度的列表，例如：[("Alice", 0.92), ("Bob", 0.87), ("Charlie", 0.75)]
         # 遍历识别结果并将结果填充到标签
        for i, (name, confidence) in enumerate(results):
            if i == 0:
                self.label_4.setText(f"{name}")           # 第1个人名字
                self.label_6.setText(f"{confidence * 100:.2f}%")  # 第1个置信度
            elif i == 1:
                self.label_8.setText(f"{name}")           # 第2个人名字
                self.label_10.setText(f"{confidence * 100:.2f}%")  # 第2个置信度
            elif i == 2:
                self.label_12.setText(f"{name}")           # 第3个人名字
                self.label_14.setText(f"{confidence * 100:.2f}%")  # 第3个置信度

                




    def show_camera(self):
        ret, self.image = self.cap.read()  # 读取摄像头图像
        if not ret or self.image is None:
            logging.warning("无法读取摄像头帧，可能是摄像头未打开或 ID 不正确")
            return  # 直接返回，避免后续报错

        self.image , self.face = my_camera.find_face(self.image)  # 检测人脸
        if self.image is None:  # 确保 find_face 没有返回 None
            logging.warning("人脸检测失败或输入图像为空，跳过后续处理")
            return

        self.image = cv2.flip(self.image, 1)  # 镜像显示
        self.image = cv2.cvtColor(self.image, cv2.COLOR_BGR2RGB)  # 转换为 RGB 格式
        self.image = cv2.resize(self.image, (600, 450))  # 缩放显示

        # 将图像转换为 QPixmap 并显示
        q_img = QtGui.QImage(self.image.data, self.image.shape[1], self.image.shape[0], QtGui.QImage.Format_RGB888)
        self.label.setPixmap(QtGui.QPixmap.fromImage(q_img))
        if not self.face is None:
            logging.info(f"find face, shape: {self.face.shape},on camera: {self.camera_id[self.id]}")
            results = pca.face_recognition(self.face,int(self.comboBox.currentText()))  # 调用 pca.py 中的 recognize_face 函数
            self.display_recognition_results(results)  # 显示识别结果



    def confirmation_dialog(self):
        if self.face is None:
            QMessageBox.warning(self, "提示", "未检测到人脸，请重试！")
            return

        self.timer.stop()
        dialog_com = ConfirmationDialog(self)  
        name = dialog_com.set_face(self.face,self.lineEdit.text())  # 传递人脸数据
        result = dialog_com.exec_()  
        logging.info(f"用户输入的姓名为：{name}")
        if result == QDialog.Accepted:
            logging.info("用户确认，执行相应操作...")
            pca.add_face(name, self.face)  # 调用 pca.py 中的 add_face 函数
            self.lineEdit.clear()  # 清空输入框
        else:
            logging.info("用户取消操作")
            
        self.timer.start(30)  



class ConfirmationDialog(QDialog):
    def __init__(self, parent=None):
        super(ConfirmationDialog, self).__init__(parent)
        self.ui = Ui_Dialog()
        self.ui.setupUi(self)
        self.parent = parent  
        self.picture = None  

    def set_face(self, face_img,name=None):
        if face_img is None:
            return
        self.picture = cv2.flip(face_img, 1)
        self.picture = cv2.cvtColor(self.picture, cv2.COLOR_BGR2RGB)
        self.picture = cv2.resize(self.picture, (200, 200))
        self.ui.lineEdit.setText(name)

        q_img = QtGui.QImage(self.picture, self.picture.shape[1], self.picture.shape[0], self.picture.strides[0], QtGui.QImage.Format_RGB888)
        self.ui.label.setPixmap(QtGui.QPixmap.fromImage(q_img))
        return self.ui.lineEdit.text()





if __name__ == '__main__':
    pca.initialize_data()  # 初始化数据
    app = QtWidgets.QApplication(sys.argv)  # 创建QApplication对象
    dialog = MyForm()  # 创建Dialog实例
    
    dialog.show()  # 显示窗口
    sys.exit(app.exec_())       # 进入消息循环
